/************************************************************************

								Heroes IV
					  Copyright 2001, The 3DO Company

	------------------------------------------------------------------
  						 obelisk_reward.cpp

	$Header: $

	$NoKeywords: $

 ************************************************************************/


#include "precompiled.h"
#include "obelisk_reward.h"

#include "army.h"
#include "basic_dialog.h"
#include "default_artifacts.h"
#include "materials.h"
#include "obelisk_reward_type.h"
#include "player.h"
#include "sized_int_types.h"
#include "streambuf_operators.h"

namespace
{
	t_uint16 const k_current_version = 0;

	// -------------------------------------------------------------------
	// Does the parts of the data read common to both save files and 
	// map files 
	// -------------------------------------------------------------------
	t_obelisk_reward_ptr common_read( std::streambuf & stream, int & version )
	{
		version = get< t_uint16 >( stream );
	
		if ( version > k_current_version )
			return t_obelisk_reward_ptr();

		std::string keyword;

		if ( !read_string16( stream, keyword ) )
			return t_obelisk_reward_ptr();

		t_obelisk_reward_type reward_type = get_reward_type_from_keyword( keyword );

		t_obelisk_reward_ptr result;

		switch(reward_type)
		{
			case k_obelisk_reward_artifact:
				result = new t_obelisk_reward_artifact;
				break;

			case k_obelisk_reward_material:
				result = new t_obelisk_reward_material;
				break;

			default:
				return t_obelisk_reward_ptr();
		}

		return result;
	}
}

// -------------------------------------------------------------------
// t_obelisk_reward base class members
// -------------------------------------------------------------------

// -------------------------------------------------------------------
// Read a reward in from a save file; create & return the correct type
// Returns a NULL pointer if data is bad
// -------------------------------------------------------------------
t_obelisk_reward_ptr t_obelisk_reward::read( std::streambuf & stream )
{
	int version; 
	t_obelisk_reward_ptr result = common_read( stream, version );

	if ( result.get() != NULL )
	{
		if ( !result->read_data( stream, version ) )
			return t_obelisk_reward_ptr();
	}

	return result;
}

// -------------------------------------------------------------------
// Give player rewards.
// -------------------------------------------------------------------
void t_obelisk_reward::give_reward( t_army * army )
{
}

void t_obelisk_reward::add_to_basic_dialog( t_basic_dialog& dialog )
{
}

// -------------------------------------------------------------------
// Read a reward in from a map file; create & return the correct type
// Returns a NULL pointer if data is bad
// -------------------------------------------------------------------
t_obelisk_reward_ptr t_obelisk_reward::read_from_map( std::streambuf & stream )
{
	int version; 
	t_obelisk_reward_ptr result = common_read( stream, version );

	if ( result.get() != NULL )
	{
		if ( !result->read_data_from_map( stream, version ) )
			return t_obelisk_reward_ptr();
	}

	return result;
}


// -------------------------------------------------------------------
// t_obelisk_reward_artifact class members
// -------------------------------------------------------------------

// -------------------------------------------------------------------
// -------------------------------------------------------------------
t_obelisk_reward_artifact::t_obelisk_reward_artifact()
	: m_count(1)
{
	
}

// -------------------------------------------------------------------
// -------------------------------------------------------------------
t_obelisk_reward_artifact::t_obelisk_reward_artifact( t_artifact_type type, t_uint32 count )
	: m_count( count ), m_artifact( get_default_artifact( type ) )
{

}
						  
// -------------------------------------------------------------------
// Read type-specific data from a save file
// -------------------------------------------------------------------
bool t_obelisk_reward_artifact::read_data( std::streambuf & stream, int version )
{
	if ( !m_artifact.read( stream ) )
		return false;

	m_count = get< t_uint32 >( stream );

	return true;
}

// -------------------------------------------------------------------
// Read type-specific data from a map file
// -------------------------------------------------------------------
bool t_obelisk_reward_artifact::read_data_from_map( std::streambuf & stream, int version )
{
	if ( !::read_from_map( stream, m_artifact ) )
		return false;

	m_count = get< t_uint32 >( stream );

	return true;
}

// -------------------------------------------------------------------
// Write to a save file
// -------------------------------------------------------------------
bool t_obelisk_reward_artifact::write( std::streambuf & stream ) const
{
	put< t_uint16 >( stream, k_current_version );
	if ( !write_string16( stream, k_obelisk_reward_keywords[ k_obelisk_reward_artifact ] ) )
		return false;

	if ( !m_artifact.write( stream ) )
		return false;

	put< t_uint32 >( stream, m_count );

	return true;
}

// -------------------------------------------------------------------
// Give player rewards.
// -------------------------------------------------------------------
void t_obelisk_reward_artifact::give_reward( t_army * army )
{
    int i;
    for (i=0; i<m_count; i++)
	    army->add( m_artifact );
}

void t_obelisk_reward_artifact::add_to_basic_dialog( t_basic_dialog& dialog )
{
	dialog.add_artifact( m_artifact, m_count );
}

// -------------------------------------------------------------------
// t_obelisk_reward_material class members
// -------------------------------------------------------------------

// -------------------------------------------------------------------
// -------------------------------------------------------------------
t_obelisk_reward_material::t_obelisk_reward_material()
	: m_amount( 1 ), m_material( k_gold )
{
	
}

// -------------------------------------------------------------------
// -------------------------------------------------------------------
t_obelisk_reward_material::t_obelisk_reward_material( t_material material, t_uint32 amount )
	: m_amount( amount ), m_material( material )
{

}

// -------------------------------------------------------------------
// Read type-specific data from a save file
// -------------------------------------------------------------------
bool t_obelisk_reward_material::read_data( std::streambuf & stream, int version )
{
	m_material = t_material( get< t_uint8 >( stream ) );

	m_amount = get< t_uint32 >( stream );

	return true;
}

// -------------------------------------------------------------------
// Read type-specific data from a map file
// -------------------------------------------------------------------
bool t_obelisk_reward_material::read_data_from_map( std::streambuf & stream, int version )
{
	m_material = t_material( get< t_uint8 >( stream ) );

	m_amount = get< t_uint32 >( stream );

	return true;
}

// -------------------------------------------------------------------
// Write to a save file
// -------------------------------------------------------------------
bool t_obelisk_reward_material::write( std::streambuf & stream ) const
{
	put< t_uint16 >( stream, k_current_version );
	if ( !write_string16( stream, k_obelisk_reward_keywords[ k_obelisk_reward_material ] ) )
		return false;

	put< t_uint8 >( stream, m_material );

	put< t_uint32 >( stream, m_amount );

	return true;
}

// -------------------------------------------------------------------
// Give player rewards.
// -------------------------------------------------------------------
void t_obelisk_reward_material::give_reward( t_army * army )
{
	t_player* player_ptr = army->get_owner();
	
    player_ptr->gain( m_material, m_amount );
}

void t_obelisk_reward_material::add_to_basic_dialog( t_basic_dialog& dialog )
{
	dialog.add_material( m_material, m_amount );
}
